local CopyL = require("copy.CopyL")
local CopyDefine = require("copy.Define")
local ObjHuman = require("core.ObjHuman")
local ExcelMap = require("excel.Map")
local DHFightConfig = require("excel.DHFight")
local Timer = require("core.Timer")
local Map = require("core.Map")
local Msg = require("core.Msg")
local Obj = require("core.Obj")
local Lang = require("common.Lang")
local DailyActFL = require("activity.DailyActFL")
local ActDefine = require("activity.Define")
local MapScan = require("core.MapScan")
local BagLogic = require("bag.BagLogic")
local ItemDefine = require("bag.ItemDefine")
local Grid = require("bag.Grid")
local Util = require("common.Util")
local RoleHandler = require("role.HandlerL")
local ExcelLevelRewardConf = require("excel.LevelReward")
local Buffer = require("buffer.Buffer")
local Broadcast = require("broadcast.Broadcast")
local HtmlUtil = require("common.HtmlUtil")
local MailLogicFL = require("mail.MailLogicFL")
local SceneEvent = require("core.SceneEvent")
local Config = require("Config")
local CopyConfig = ExcelMap.copy
local DHFightBaseConfig = DHFightConfig.Base[1]
local DHFightRewardConfig = DHFightConfig.Reward[1]
local DHFightIncomeConfig = DHFightConfig.Income[1]
local CollectConfig = require("excel.Collect").Collect
local WorldDropConfig = require("excel.WorldDrop")
local CopyHandler = require("copy.HandlerL")
local Log = require("common.Log")

-------------------------
--该副本组必须都在同一个逻辑线程内
-------------------------

DHFIGHT_STATUS_LEAVED   =          -1           --离开战场
DHFIGHT_STATUS_NORMAL   =           0           --正常状态
DHFIGHT_STATUS_DIE      =           1           --已经死亡

DHFIGHT_FLOOR_ERROR     =          -1 
DHFIGHT_FLOOR_1         =           1
DHFIGHT_FLOOR_2         =           2
DHFIGHT_FLOOR_3         =           3
DHFIGHT_FLOOR_4         =           4
DHFIGHT_FLOOR_5         =           5

HumanWarDataList = HumanWarDataList or nil 
FloorDataList = FloorDataList or {}
RoomRankList = RoomRankList or {}
HeartBeatCount = HeartBeatCount or {}
KillList = KillList or {}

function checkEnter(human)
    local nStartTime, nEndTime = getActTime()
    if nStartTime > 0 and nEndTime > 0 then

    else
        Broadcast.sendBroadcast(human, Lang.DOWN, Lang.DHFIGHT_NOT_START)  --活动暂未开启
        return false
    end
    return true
end

function onGetHumanCurFloor(humanUuid)
    if not HumanWarDataList then
        return
    end

    local nRoomID = CopyL.copyHuman2Room[humanUuid]
    if nRoomID and nRoomID > 0 and HumanWarDataList._humanDataList[humanUuid] then
        return HumanWarDataList._humanDataList[humanUuid].curfloor
    end
end

function onGetHumanOldFloor(humanUuid)
    if not HumanWarDataList then
        return
    end

    local nRoomID = CopyL.copyHuman2Room[humanUuid]
    if nRoomID and nRoomID > 0 and HumanWarDataList._humanDataList[humanUuid] then
        return HumanWarDataList._humanDataList[humanUuid].oldfloor
    end
end

local function get_grid(itemID, itemNum, itemColor)
    local grid = Grid.create(nil, itemID, itemNum, nil, ItemDefine.qualityOut[itemColor])
    return grid
end


function onGetHumanStatus(humanUuid, roomID)
    return HumanWarDataList._humanDataList[humanUuid] and HumanWarDataList._humanDataList[humanUuid].status or DHFIGHT_STATUS_LEAVED
end

function onDHFightRoomBegin(copyID, roomID)
    if copyID == CopyDefine.COPY_DHFIGHT_ID1 then
        local nStartTime = getActTime()
        if not HumanWarDataList or (HumanWarDataList and HumanWarDataList.version ~= nStartTime)then
            HumanWarDataList = {}
            HumanWarDataList._roomData = {}
            HumanWarDataList._humanDataList = {}
            HumanWarDataList.static = 0    -- 0 战斗状态 1 结束状态
            HumanWarDataList.version = nStartTime
            HumanWarDataList.startTime = Timer.now 
            HumanWarDataList.beginRoom = roomID 
            FloorDataList = {[DHFIGHT_FLOOR_1] = {}, [DHFIGHT_FLOOR_2] = {}, [DHFIGHT_FLOOR_3] = {}, [DHFIGHT_FLOOR_4] = {}, [DHFIGHT_FLOOR_5] = {}}
            RoomRankList = {}
        end
    end

    RoomRankList[roomID] = {}
    HeartBeatCount[roomID] = 0
    KillList[roomID] = {}
end

--得到开始时间
function getActTime()
    local nActData = getActData() 
    if not nActData or nActData.status ~= ActDefine.ACT_STATE_RUNNING then
        return 0, 0
    end
    return nActData.startTime, nActData.endTime
end

--得到活动剩余时间
function getLeftTime()
    local nActData = getActData()
    if not nActData or nActData.status ~= ActDefine.ACT_STATE_RUNNING then
        return 0
    end
    local t =  nActData.endTime - os.time()
    if t < 0 then t = 0 end
    return t
end

function getFloorLeftTime(floor, roomID)
	--local nCalcTime = DHFightBaseConfig.floorTime[floor]
    --if nCalcTime then
    --    for k, v in ipairs(nCalcTime) do
    --        if v >= (HeartBeatCount[HumanWarDataList.beginRoom] or 0) then
    --            local nAlgTime = (v - HeartBeatCount[HumanWarDataList.beginRoom])
    --            return nAlgTime
    --            --return nCalcTime - (nAlgTime == 0 and nCalcTime or nAlgTime)
    --        end
    --    end
    --end
    --return nil 

    --local nCalcTime = DHFightBaseConfig.floorTime[floor]
    --local nAlgTime = (Timer.now - HumanWarDataList.startTime) / 1000
    --
    --if nCalcTime and nAlgTime > 0 then
    --    for k, v in ipairs(nCalcTime) do
    --        if v - nAlgTime >= 0 then
    --            local nLeftTime = v - nAlgTime 
    --            return nLeftTime
    --        end
    --    end
    --end
    --return nil
	
	local nCalcTime = DHFightBaseConfig.floorTime[floor]
    local nStartTime, nEndTime = getActTime()
    local nAlgTime = os.time() - nStartTime 
    if nCalcTime and nAlgTime > 0 then
        for k, v in ipairs(nCalcTime) do
            if v >=  nAlgTime then
                local nLeftTime = v - nAlgTime 
                return nLeftTime, nAlgTime
            end
        end
    end
    return nil, nil 
end

function getActData()
    return DailyActFL.onGetActData(ActDefine.ACT_TYPE_DHFIGHT_ACT)
end

function onDHFightHumanEndCopy(human, copyID, roomID)
    onHumanCtl(human, roomID, copyID)
end

function onJumpFloor(copyID, roomID)
    local nJumpList = {}
    if RoomRankList[roomID] then
        for k, v in ipairs(RoomRankList[roomID]) do
            local nHuman = ObjHuman.onlineUuid[v[3]]
            if nHuman and nHuman.fd then
                local floor = onGetHumanCurFloor(nHuman._id)
                if floor >= DHFIGHT_FLOOR_5 then
                    break
                end
                if k > DHFightBaseConfig.rankJumpFloor[floor] then
                    break
                end
                local nFloorLeftTime, nFloorAlgTime = getFloorLeftTime(floor, roomID)
                if nFloorLeftTime and nFloorLeftTime == 0 then
                    if onGetHumanCurFloor(nHuman._id) == floor then
                        local nTempCopyID = CopyL.isCopyBySceneID(nHuman.scene_id)
                        if nTempCopyID == copyID then
                            print("has cross jump")
                            if nHuman.db.hp <= 0 then
                                RoleHandler.CG_REVIVE_GO_HOME(nHuman, true)
                            end

                            nHuman.db.dhfightcurfloor = floor + 1
                            HumanWarDataList._humanDataList[v[3]].curfloor = floor + 1
                            FloorDataList[floor][v[3]] = nil 

                            if floor == DHFIGHT_FLOOR_1 then
                                CopyL.humanEndCopy(nHuman, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID3})
                                CopyHandler.CG_COPY_ENTER(nHuman, {copyID = CopyDefine.COPY_DHFIGHT_ID3})
                                Log.write(Log.LOGID_TEST, nHuman._id, nHuman.account, nHuman.name, nHuman.db.lv, k, v[2], nFloorAlgTime, roomID, floor, floor + 1, copyID, CopyDefine.COPY_DHFIGHT_ID3)
                            elseif floor == DHFIGHT_FLOOR_2 then                                                                    
                                CopyL.humanEndCopy(nHuman, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID2})                  
                                CopyHandler.CG_COPY_ENTER(nHuman, {copyID = CopyDefine.COPY_DHFIGHT_ID2})                           
                                Log.write(Log.LOGID_TEST, nHuman._id, nHuman.account, nHuman.name, nHuman.db.lv, k, v[2], nFloorAlgTime, roomID, floor, floor + 1, copyID, CopyDefine.COPY_DHFIGHT_ID2)
                            elseif floor == DHFIGHT_FLOOR_3 then                                                                    
                                CopyL.humanEndCopy(nHuman, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID4})                  
                                CopyHandler.CG_COPY_ENTER(nHuman, {copyID = CopyDefine.COPY_DHFIGHT_ID4})                           
                                Log.write(Log.LOGID_TEST, nHuman._id, nHuman.account, nHuman.name, nHuman.db.lv, k, v[2], nFloorAlgTime, roomID, floor, floor + 1, copyID, CopyDefine.COPY_DHFIGHT_ID4)
                            elseif floor == DHFIGHT_FLOOR_4 then                                                                    
                                CopyL.humanEndCopy(nHuman, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID5})                  
                                CopyHandler.CG_COPY_ENTER(nHuman, {copyID = CopyDefine.COPY_DHFIGHT_ID5})                           
                                Log.write(Log.LOGID_TEST, nHuman._id, nHuman.account, nHuman.name, nHuman.db.lv, k, v[2], nFloorAlgTime, roomID, floor, floor + 1, copyID, CopyDefine.COPY_DHFIGHT_ID5)
                            end
                            nJumpList[nHuman._id] = roomID 
                        end
                    end
                end
            end
        end
    end

    for k, v in pairs(nJumpList) do
        for kk, vv in ipairs(RoomRankList[v]) do
            if k == vv[3] then
                table.remove(RoomRankList[v], kk)
            end
        end
    end
end

function onDHFightHumanEnterCopy(human, copyID, roomID)
    if not HumanWarDataList._humanDataList[human._id] then
        HumanWarDataList._humanDataList[human._id] = {v3 = 0, exp = 0, killNum = 0 ,status = DHFIGHT_STATUS_NORMAL, bufAddCount = 0, oldfloor = DHFIGHT_FLOOR_1, curfloor = DHFIGHT_FLOOR_1}
        FloorDataList[DHFIGHT_FLOOR_1][human._id] = human
        human.db.dhfightcurfloor = DHFIGHT_FLOOR_1 
        onJumpBackPos(human)

        local nEnterAddBufIDList = DHFightBaseConfig.enterAddBufID
        if nEnterAddBufIDList then
            for k, v in pairs(nEnterAddBufIDList) do
                Buffer.add(v, human, human)
            end
        end
        local mm = Msg.gc.GC_SHOW_TXT
        mm.txt = Lang.DHFIGHT_FIRSTENTER 
        Msg.send(mm, human.fd)
    else
        local nCurFloor = onGetHumanCurFloor(human._id)
        local nOldFloor = onGetHumanOldFloor(human._id)
        HumanWarDataList._humanDataList[human._id].status = DHFIGHT_STATUS_NORMAL
        if nCurFloor ~= nOldFloor and nCurFloor > nOldFloor then
            FloorDataList[nCurFloor][human._id] = human
            HumanWarDataList._humanDataList[human._id].oldfloor = nCurFloor 
            onAddV3(HumanWarDataList._humanDataList[human._id].v3, human, true)

            if nCurFloor == DHFIGHT_FLOOR_2 and copyID ~= CopyDefine.COPY_DHFIGHT_ID3 then
                CopyL.humanEndCopy(human, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID3})
                CopyHandler.CG_COPY_ENTER(human, {copyID = CopyDefine.COPY_DHFIGHT_ID3})

            elseif nCurFloor == DHFIGHT_FLOOR_3 and copyID ~= CopyDefine.COPY_DHFIGHT_ID2 then
                CopyL.humanEndCopy(human, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID2})
                CopyHandler.CG_COPY_ENTER(human, {copyID = CopyDefine.COPY_DHFIGHT_ID2})

            elseif nCurFloor == DHFIGHT_FLOOR_4 and copyID ~= CopyDefine.COPY_DHFIGHT_ID4 then
                CopyL.humanEndCopy(human, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID4})
                CopyHandler.CG_COPY_ENTER(human, {copyID = CopyDefine.COPY_DHFIGHT_ID4})

            elseif nCurFloor == DHFIGHT_FLOOR_5 and copyID ~= CopyDefine.COPY_DHFIGHT_ID5 then
                CopyL.humanEndCopy(human, copyID, roomID, {copyID = CopyDefine.COPY_DHFIGHT_ID5})
                CopyHandler.CG_COPY_ENTER(human, {copyID = CopyDefine.COPY_DHFIGHT_ID5})
            else
                --local nTemp = nCurFloor
                --if copyID == CopyDefine.COPY_DHFIGHT_ID2 then
                --    nTemp = nCurFloor % 3 + 1
                --elseif copyID == CopyDefine.COPY_DHFIGHT_ID3 then
                --    nTemp = nCurFloor - 1
                --enj
                --local nMapID = CopyConfig[copyID].mapList[nTemp]
                local nMapID = CopyConfig[copyID].mapList[1]
                if nMapID and nMapID > 0 then
                    if human.db.map_id ~= nMapID then
                        local nSceneID = CopyL.copyList[copyID][roomID][nMapID]
                        local nX, nY = Map.getRandPointByMapID(nMapID)
                        --local nX, nY = onGetRondomBorn(nCurFloor, nSceneID)
                        ObjHuman.enterMap(human, nMapID, nX, nY)
                    end
                end
            end

            if nCurFloor ~= DHFIGHT_FLOOR_5 then
                onJumpBackPos(human)
            end

            local nRankRewardList = nil
            for i = nOldFloor + 1, nCurFloor do
                nRankRewardList = {}
                if DHFightRewardConfig.jumpFloorReward[i - 1] then 
                    nRankRewardList[#nRankRewardList + 1] = get_grid(DHFightRewardConfig.jumpFloorReward[i - 1][1], 1)
                    MailLogicFL.CreateNewMailForUser(human._id, Lang.DHFIGHT_MAIL_JUMPREWARDTITLE, string.format(Lang.DHFIGHT_MAIL_JUMPREWARDCONTENT, i), nRankRewardList)
                end
            end
            if nRankRewardList then
                local nSendMsg = Msg.gc.GC_DHFIGHT_JUMPFLOORREWARD
                nSendMsg.floor = nCurFloor
                nSendMsg.msg = DHFightRewardConfig.jumpFloorReward[nOldFloor] and DHFightRewardConfig.jumpFloorReward[nOldFloor][2] or ""
                nSendMsg.jumpfloorreward.reward[0] = 0
                for k, v in ipairs(nRankRewardList) do
                    nSendMsg.jumpfloorreward.reward[0] = nSendMsg.jumpfloorreward.reward[0] + 1 
                    local nItemData = nSendMsg.jumpfloorreward.reward[nSendMsg.jumpfloorreward.reward[0]]
                    Grid.makeItem(v, nItemData)
                end
                Msg.send(nSendMsg, human.fd)
            end
        end
    end
    human.enterCopyTime = Timer.now
    human.db.dhfightEnterTime = os.time() 
    onSendConfigData(human, copyID)
    if HumanWarDataList._humanDataList[human._id].kingMsgCD then
        onSendKingMsgData(human)
    end
end

CollectRewarData = nil
function initCollectRewarData()
    CollectRewarData = {}
    for k, v in pairs(DHFightBaseConfig.floorCollectData) do
        if not CollectRewarData[k] then
            CollectRewarData[k] = {}
        end
        for __, nCollectID in ipairs(v) do
            if CollectConfig[nCollectID] then
                local nWorldDropID = CollectConfig[nCollectID].world_drop_id
                if WorldDropConfig[nWorldDropID] then
                    for __, nDropData in pairs(WorldDropConfig[nWorldDropID]) do
                        for __, nItemData in ipairs(nDropData.items) do
                            local grid = get_grid(nItemData[1], nItemData[3])
                            table.insert(CollectRewarData[k], grid)
                        end
                    end
                end
            end
        end
    end
end

V3RewardData = nil
function initV3RewarData()
    V3RewardData = {}
    if DHFightRewardConfig.v3Reward then
        for k, v in ipairs(DHFightRewardConfig.v3Reward) do
            V3RewardData[v[1]] = {}
            for kk, vv in ipairs(v[2]) do
                V3RewardData[v[1]][#V3RewardData[v[1]] + 1] = get_grid(vv[1], vv[2], vv[3])
            end
        end
    end
end

function onSendConfigData(human, copyID)
    local nFloor = onGetHumanCurFloor(human._id)
    if nFloor and nFloor > 0 then
        local nSendMsg = Msg.gc.GC_DHFIGHT_CONFIGDATA
        nSendMsg.floor = nFloor 
        nSendMsg.jumpRankLess = DHFightBaseConfig.rankJumpFloor[nFloor] or 0

        -- 当层跳层奖励
        if DHFightRewardConfig.jumpFloorReward[nFloor] then
            nSendMsg.nextfloorreward.reward[0] = 0 
            for k, v in ipairs(DHFightRewardConfig.jumpFloorReward) do
                nSendMsg.nextfloorreward.reward[0] = nSendMsg.nextfloorreward.reward[0] + 1
                local nItemData = nSendMsg.nextfloorreward.reward[nSendMsg.nextfloorreward.reward[0]]
                local grid = get_grid(v[1], 1)
                Grid.makeItem(grid, nItemData)
            end
        end

        nSendMsg.kingmsgcdtime = DHFightBaseConfig.kingMsgCD 
        for k, v in ipairs(DHFightBaseConfig.kingMsg) do
            nSendMsg.kingmsg = (nSendMsg.kingmsg or "") .. v 
        end

        -- 参与奖
        nSendMsg.joinreward.reward[0] = 0 
        for k, v in ipairs(DHFightRewardConfig.joinReward) do
            nSendMsg.joinreward.reward[0] = nSendMsg.joinreward.reward[0] + 1
            local nItemData = nSendMsg.joinreward.reward[nSendMsg.joinreward.reward[0]]
            local grid = get_grid(v[1], v[2], v[3])
            Grid.makeItem(grid, nItemData)
        end

        -- 每层掉落物数据
        if not CollectRewarData then
            initCollectRewarData()
        end

        nSendMsg.floorCollectreward[0] = 0
        for k, v in pairs(CollectRewarData) do
            nSendMsg.floorCollectreward[0] = nSendMsg.floorCollectreward[0] + 1   
            local nCollectMsgData = nSendMsg.floorCollectreward[nSendMsg.floorCollectreward[0]]
            nCollectMsgData.floor = k
            nCollectMsgData.reward[0] = 0
            for __, nItemGridData in ipairs(v) do
                nCollectMsgData.reward[0] = nCollectMsgData.reward[0] + 1
                local nItemMsgData = nCollectMsgData.reward[nCollectMsgData.reward[0]]
                Grid.makeItem(nItemGridData, nItemMsgData)
            end
        end

        if not V3RewardData then
            initV3RewarData()
        end

        nSendMsg.v3reward[0] = 0
        for k, v in pairs(V3RewardData) do
            nSendMsg.v3reward[0] = nSendMsg.v3reward[0] + 1   
            local nV3RewardMsgData = nSendMsg.v3reward[nSendMsg.v3reward[0]]
            nV3RewardMsgData.score = k
            nV3RewardMsgData.reward[0] = 0
            for __, nItemGridData in ipairs(v) do
                nV3RewardMsgData.reward[0] = nV3RewardMsgData.reward[0] + 1
                local nItemMsgData = nV3RewardMsgData.reward[nV3RewardMsgData.reward[0]]
                Grid.makeItem(nItemGridData, nItemMsgData)
            end
        end
        Msg.send(nSendMsg, human.fd)
    end
end

function onSendCopyData(copyID, roomID, sceneID)

    local nSendMsg = Msg.gc.GC_DHFIGHT_COPYDATA
    nSendMsg.actleftTime = getLeftTime()

    nSendMsg.rankList[0] = 0
    for nRank, nRankData in ipairs(RoomRankList[roomID]) do
        nSendMsg.rankList[0] = nSendMsg.rankList[0] + 1
        local nRankMsgData = nSendMsg.rankList[nSendMsg.rankList[0]]
        if nRankMsgData then
            nRankMsgData.name = nRankData[1]
            nRankMsgData.score = nRankData[2]
            nRankMsgData.uuid = nRankData[3]
            nRankMsgData.floor = onGetHumanCurFloor(nRankData[3]) or DHFIGHT_FLOOR_ERROR
            nRankMsgData.zdl = nRankData[4]
            nRankMsgData.killnum = HumanWarDataList._humanDataList[nRankData[3]].killNum or 0
        end
        if nRank >= 10 then
            break
        end
    end

    nSendMsg.myScore = 0
    nSendMsg.myExp = 0
    nSendMsg.myKillNum = 0
    nSendMsg.floorleftTime = 0

    local nFds = Obj.scenes_fds[sceneID]
    if nFds then
        for k, v in pairs(nFds) do
            if v.obj_type == Obj.TYPE_HUMAN then
                local nFloor = onGetHumanCurFloor(v._id)
                if nFloor and nFloor > 0 then
                    nSendMsg.floor = nFloor
                    nSendMsg.floorleftTime = getFloorLeftTime(nFloor, roomID) or 0
                    nSendMsg.myScore = HumanWarDataList._humanDataList[v._id] and HumanWarDataList._humanDataList[v._id].v3 or 0
                    nSendMsg.myExp = HumanWarDataList._humanDataList[v._id] and HumanWarDataList._humanDataList[v._id].exp or 0
                    nSendMsg.myKillNum = HumanWarDataList._humanDataList[v._id] and HumanWarDataList._humanDataList[v._id].killNum or 0
                    Msg.send(nSendMsg, k)
                end
            end
        end
    end
end

function onSendPKData(diffNum, humanList)
    local nSendMsg = Msg.gc.GC_DHFIGHT_PKDATA
    nSendMsg.curLen = diffNum
    for k, v in pairs(humanList) do
        Msg.send(nSendMsg, v.fd)
    end
end

function onGetPKAreaData(mapID, copyID, roomID)
    local nCenterRedNum = 0
    local nCenterBlueNum = 0
    local nSceneID = CopyL.copyList[copyID][roomID][mapID]
    if not nSceneID or nSceneID <= 0 then
        return
    end
    local nSum, nHumanList = MapScan.scanAreaLiveHuman(mapID, nSceneID, DHFightBaseConfig.centerAreaID)
    if nSum > 0 then
        for nHumanUuid in pairs(nHumanList) do
            local nFloor = onGetHumanCurFloor(nHumanUuid)
            if nFloor == BLUE_SIDE then
                nCenterBlueNum = nCenterBlueNum + 1
            elseif nFloor == RED_SIDE then
                nCenterRedNum = nCenterRedNum + 1
            end
        end
    end
    return nCenterRedNum, nCenterBlueNum, nHumanList
end

--function onGetRondomBorn(floor, scene_id, begin)
--    local nAreaID = DHFightBaseConfig.bornAreaID[floor]
--    if nAreaID then
--        return Map.getPositionInArea(scene_id, nAreaID, true)
--    end
--    return nil, nil
--end

function onDHFightOneSec(copyID, roomID)
    if not HumanWarDataList or HumanWarDataList.static == 1 or not HeartBeatCount[roomID] then
        return
    end

    HeartBeatCount[roomID] = HeartBeatCount[roomID] + 1

    onJumpFloor(copyID, roomID)
    --集体复活
    if HeartBeatCount[roomID] % DHFightBaseConfig.humanReliveTime == 0 then
        local humanList = CopyL.getCopyHumanList(copyID, roomID)
        for k, v in pairs(humanList) do
            if v.db.hp <= 0 then
                local nTempCopyID = CopyL.isCopyBySceneID(v.scene_id)
                if nTempCopyID == copyID then
                    RoleHandler.CG_REVIVE_GO_HOME(v, true)
                end
            end
        end
    end

    local nAddExpTime = HeartBeatCount[roomID] % DHFightBaseConfig.addExpTime == 0 and true or false

    if nAddExpTime then
        local nHumanList = CopyL.getCopyHumanList(copyID, roomID)
        for k, v in pairs(nHumanList) do
            ObjHuman.addExp(v, ExcelLevelRewardConf[8][v.db.lv].exp)
            if HumanWarDataList._humanDataList[v._id] then
                HumanWarDataList._humanDataList[v._id].exp = HumanWarDataList._humanDataList[v._id].exp + ExcelLevelRewardConf[8][v.db.lv].exp
            end
        end
    end

    --发送副本数据面板数据
    local nCopyConfig = CopyConfig[copyID]
    if HeartBeatCount[roomID] % 3 == 0 then
        for k, v in pairs(nCopyConfig.mapList) do
            local nSceneID = CopyL.copyList[copyID][roomID][v]
            onSendCopyData(copyID, roomID, nSceneID)
        end
    end
end

function onGetReviveTime(humanUuid)
    local nRoomID = CopyL.copyHuman2Room[humanUuid]
    if HeartBeatCount[nRoomID] then
        if HumanWarDataList.static == 1 then
            return 0
        else
            local nLeftTime = HeartBeatCount[nRoomID] % DHFightBaseConfig.humanReliveTime
            return DHFightBaseConfig.humanReliveTime - (nLeftTime == 0 and DHFightBaseConfig.humanReliveTime or nLeftTime)
        end
    end
end

function onJumpBackPos(human, isDead)
    if not HumanWarDataList or HumanWarDataList.static == 1 then
        local nX, nY = Map.getRandPointByMapID(human.db.map_id)
        --local nX, nY = onGetRondomBorn(human.db.dhfightcurfloor, human.scene_id)
        Obj.jump(human, nX, nY, Msg.gc.GC_JUMP)
    else
        local nHumanWarData = HumanWarDataList._humanDataList[human._id]
        if not nHumanWarData then
            return
        end
        local nFloor = onGetHumanCurFloor(human._id)
        if nFloor and nFloor > 0 then
            local nX, nY = Map.getRandPointByMapID(human.db.map_id)
            --local nX, nY = onGetRondomBorn(nFloor, human.scene_id)
            Obj.jump(human, nX, nY, Msg.gc.GC_JUMP)
        end

        if isDead and nHumanWarData and nHumanWarData.bufAddCount < DHFightBaseConfig.dieAddBufCount then
            local nAddBufIDList = DHFightBaseConfig.dieAddBufID
            if nAddBufIDList then
                for k, v in pairs(nAddBufIDList) do
                    Buffer.add(v, human, human)
                end
            end
            nHumanWarData.bufAddCount = nHumanWarData.bufAddCount + 1

            local nReviveBufIDList = DHFightBaseConfig.reviveAddBufID
            if nReviveBufIDList then
                for k, v in pairs(nReviveBufIDList) do
                    Buffer.add(v, human, human)
                end
            end
        end
    end
end

function onCheckComboKill()
    local nSendMsg = Msg.gc.GC_DHFIGHT_COMBOKILL
    for nRoomID, nRoomKillData  in pairs(KillList) do
        for nHumanUuid, nKillData in pairs(nRoomKillData) do
            if nKillData.change == true then
                nKillData.change = false
                nSendMsg.killNum = nKillData.comboKillCount
                local nHuman = ObjHuman.onlineUuid[nHumanUuid]
                if nHuman then
                    Msg.send(nSendMsg, nHuman.fd)
                end
            end
        end
    end
end


--人物死亡
function onDHFightRoleDieCB(atker, human, copyID, roomID)
    if atker.obj_type ~= Obj.TYPE_HUMAN then
        return
    end

    local nKillData = KillList[roomID][atker._id]
    if nKillData then
        local nKillDiffTime = os.time() - nKillData.comboKillTime
        if nKillDiffTime <= DHFightBaseConfig.comboKillTime then
            nKillData.comboKillCount = nKillData.comboKillCount + 1
        else
            nKillData.comboKillCount = 1
        end
        nKillData.noDieComboKillCount = nKillData.noDieComboKillCount + 1
        nKillData.comboKillTime = os.time()
        nKillData.killUuid = human._id
        nKillData.change = true
    else
        KillList[roomID][atker._id] = {comboKillTime = os.time(), killUuid = human._id, comboKillCount = 1, noDieComboKillCount = 1, change = true}
        nKillData = KillList[roomID][atker._id]
    end
    HumanWarDataList._humanDataList[atker._id].killNum = HumanWarDataList._humanDataList[atker._id].killNum + 1

    --击杀增加积分
    local nDecV3 = math.ceil((HumanWarDataList._humanDataList[human._id].v3 or 0) * (DHFightIncomeConfig.rankKillAddV3[1] / 100))
    onAddV3(DHFightIncomeConfig.killHumanAddV3 + nDecV3, atker)
    onAddV3(-nDecV3, human)

    local nAddBufIDList = DHFightBaseConfig.dieAddBufID
    if nAddBufIDList then
        for k, v in pairs(nAddBufIDList) do
            Buffer.removeID(v, atker)
        end

    end

    -- 击杀广播相关
    local nContent = nil
    local nNoDieComboKillCount = nKillData.noDieComboKillCount
    local nNoDieComboKillData = DHFightBaseConfig.noDieComboMsg[nNoDieComboKillCount]
    if (nNoDieComboKillCount - 50) % DHFightBaseConfig.noDieComboKillMaxNum == 0 then
        nContent = DHFightBaseConfig.noDieComboMsg[100]
    else
        if nNoDieComboKillData then
            nContent = string.format(nNoDieComboKillData[1], HtmlUtil.font(atker.name, "#00FF00"), HtmlUtil.font(string.format(Lang.DHFIGHT_COMBOKILL, nNoDieComboKillCount), "#F1FF0A"))
            onSendBroadcast(nContent, Lang.UP, copyID, roomID)
        end
    end

    local nBeKillData = KillList[roomID][human._id]
    if nBeKillData and nBeKillData.noDieComboKillCount >= DHFightBaseConfig.breakNoDieComboKill then
        nContent = string.format(Lang.DHFIGHT_BREAK_COMBOKILL,
        HtmlUtil.font(atker.name, "#00FF00"),
        HtmlUtil.font(human.name, "#00FF00"),
        HtmlUtil.font(string.format(Lang.DHFIGHT_COMBOKILL, nBeKillData.noDieComboKillCount), "#F1FF0A"))
        nBeKillData.noDieComboKillCount = 0
        onSendBroadcast(nContent, Lang.UP, copyID, roomID)
    end

    if HeartBeatCount[roomID] % DHFightBaseConfig.humanReliveTime == 0 then
        RoleHandler.CG_REVIVE_GO_HOME(human, true)
    end
end

function onDHFightRoomFinish(copyID, roomID)
    local nRoomHumanList = CopyL.getCopyHumanList(copyID, roomID)
    for k, v in ipairs(nRoomHumanList) do
        local nHuman = ObjHuman.onlineUuid[v._id]
        if nHuman then
            --死亡的进行最后复活
            if nHuman.db.hp <= 0 then
                RoleHandler.CG_REVIVE_GO_HOME(nHuman, true)
            end
            nHuman.db.dhfightcurfloor = DHFIGHT_FLOOR_ERROR
            onHumanCtl(nHuman, roomID, copyID)
        end
    end
end

function onDHFightRoomClear(copyID, roomID)
    local nStartTime = getActTime()
    if nStartTime == 0 or (HumanWarDataList and HumanWarDataList.version ~= nStartTime) then
        HumanWarDataList = nil
        FloorDataList = nil
    end

    HeartBeatCount[roomID] = nil
    RoomRankList[roomID] = nil
    KillList[roomID] = nil 
end

function onHumanCtl(human, roomID)
    local nFloor = onGetHumanCurFloor(human._id)
    if nFloor and nFloor ~= DHFIGHT_FLOOR_ERROR and roomID then
        --FloorDataList[nFloor][human._id] = nil
        --HumanWarDataList._humanDataList[human._id] = nil
        HumanWarDataList._humanDataList[human._id].status = DHFIGHT_STATUS_LEAVED
    end

    local nAddBufIDList = DHFightBaseConfig.dieAddBufID
    if nAddBufIDList then
        for k, v in pairs(nAddBufIDList) do
            Buffer.removeID(v, human)
        end
    end

    local nReviveBufIDList = DHFightBaseConfig.reviveAddBufID
    if nReviveBufIDList then
        for k, v in pairs(nReviveBufIDList) do
            Buffer.removeID(v, human)
        end
    end
end

local function sort(a, b)
    local nFloor1 = onGetHumanCurFloor(a[3])
    local nFloor2 = onGetHumanCurFloor(b[3])
    if nFloor1 ~= nFloor2 then
        return (nFloor1 or 0) > (nFloor2 or 0)
    else
        return a[2] > b[2]
    end
end

function onDHFightRoomEnd()
    if not HumanWarDataList or HumanWarDataList.static == 1 then
        return
    end

    HumanWarDataList.static = 1

    for nRoomID in pairs(RoomRankList) do
        if HumanWarDataList then
            local nCopyConfig = CopyConfig[CopyDefine.COPY_DHFIGHT_ID1]
            if nCopyConfig then
                if nCopyConfig and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID1] and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID1][nRoomID] then
                    for k, v in pairs(nCopyConfig.mapList) do
                        local nSceneID = CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID1][nRoomID][v]
                        onSendCopyData(CopyDefine.COPY_DHFIGHT_ID1, nRoomID, nSceneID)
                    end
                    CopyL.roomFinish(CopyDefine.COPY_DHFIGHT_ID1, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
                end
            end

            nCopyConfig = CopyConfig[CopyDefine.COPY_DHFIGHT_ID2]
            if nCopyConfig then
                if nCopyConfig and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID2] and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID2][nRoomID] then
                    for k, v in pairs(nCopyConfig.mapList) do
                        local nSceneID = CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID2][nRoomID][v]
                        onSendCopyData(CopyDefine.COPY_DHFIGHT_ID2, nRoomID, nSceneID)
                    end
                    CopyL.roomFinish(CopyDefine.COPY_DHFIGHT_ID2, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
                end
            end

            nCopyConfig = CopyConfig[CopyDefine.COPY_DHFIGHT_ID3]
            if nCopyConfig then
                if nCopyConfig and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID3] and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID3][nRoomID] then
                    for k, v in pairs(nCopyConfig.mapList) do
                        local nSceneID = CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID3][nRoomID][v]
                        onSendCopyData(CopyDefine.COPY_DHFIGHT_ID2, nRoomID, nSceneID)
                    end
                    CopyL.roomFinish(CopyDefine.COPY_DHFIGHT_ID3, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
                end
            end

            nCopyConfig = CopyConfig[CopyDefine.COPY_DHFIGHT_ID4]
            if nCopyConfig then
                if nCopyConfig and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID4] and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID4][nRoomID] then
                    for k, v in pairs(nCopyConfig.mapList) do
                        local nSceneID = CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID4][nRoomID][v]
                        onSendCopyData(CopyDefine.COPY_DHFIGHT_ID4, nRoomID, nSceneID)
                    end
                    CopyL.roomFinish(CopyDefine.COPY_DHFIGHT_ID4, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
                end
            end

            nCopyConfig = CopyConfig[CopyDefine.COPY_DHFIGHT_ID5]
            if nCopyConfig then
                if nCopyConfig and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID5] and CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID5][nRoomID] then
                    for k, v in pairs(nCopyConfig.mapList) do
                        local nSceneID = CopyL.copyList[CopyDefine.COPY_DHFIGHT_ID5][nRoomID][v]
                        onSendCopyData(CopyDefine.COPY_DHFIGHT_ID5, nRoomID, nSceneID)
                    end
                    CopyL.roomFinish(CopyDefine.COPY_DHFIGHT_ID5, nRoomID, CopyDefine.COPY_FINISH_ACT_END, "活动结束")
                end
            end
        end
    end

    local nAllRankList = {}
    for nRoomID, v in pairs(RoomRankList) do
        for nRank, nRankData in ipairs(v) do
            table.insert(nAllRankList, nRankData)
        end
    end

    table.sort(nAllRankList, sort)

    local nSendMsg = Msg.gc.GC_DHFIGHT_RANKLIST
    nSendMsg.rankList[0] = 0
    for k, v in ipairs(nAllRankList) do
        nSendMsg.rankList[0] = nSendMsg.rankList[0] + 1
        local nRankMsgData = nSendMsg.rankList[nSendMsg.rankList[0]]
        if nRankMsgData then
            nRankMsgData.name = v[1]
            nRankMsgData.score = v[2]
            nRankMsgData.uuid = v[3]
            nRankMsgData.zdl = v[4]
            nRankMsgData.floor = v[5] 
            nRankMsgData.killnum = HumanWarDataList._humanDataList[v[3]].killNum or 0
        end
        if k >= 10 then
            break
        end
    end

    for i = 1, DHFightBaseConfig.maxFloor do
        local nFds = onGetFloorFds(i)
        if nFds[0] > 0 then
            Msg.sendMulti(nSendMsg, nFds)
        end
    end

    local nJoinRewardList = {} 
    if DHFightRewardConfig.joinReward then
        for k, v in ipairs(DHFightRewardConfig.joinReward) do
            nJoinRewardList[#nJoinRewardList + 1] = get_grid(v[1], v[2], v[3])
        end
    end

    if #nJoinRewardList > 0 then
        for k, v in pairs(HumanWarDataList._humanDataList) do
            MailLogicFL.CreateNewMailForUser(k, Lang.DHFIGHT_MAIL_JOINREWARDTITLE, Lang.DHFIGHT_MAIL_JOINREWARDCONTENT, nJoinRewardList)
        end
    end

    if V3RewardData then
        local nIndex = nil
        for k, v in pairs(HumanWarDataList._humanDataList) do
            for kk, vv in ipairs(DHFightRewardConfig.v3Reward) do
                if v.v3 >= vv[1] then
                    nIndex = vv[1]
                else
                    break
                end
            end

            if nIndex and V3RewardData[nIndex] then
                MailLogicFL.CreateNewMailForUser(k, Lang.DHFIGHT_MAIL_V3REWARDTITLE, Lang.DHFIGHT_MAIL_V3REWARDCONTENT, V3RewardData[nIndex])
            end
        end
    end

    Broadcast.sendBroadcast2World(Lang.UP + Lang.GROSSIP, string.format(Lang.DHFIGHT_ACT_END, nAllRankList[1] and nAllRankList[1][1] or ""))
end

-- 增加积分
function onAddV3(v3, human, enterFloor)
    local nHumanUuid = human._id
    local nRoomID = CopyL.copyHuman2Room[nHumanUuid]
    if HumanWarDataList then
        local nHumanWarData = HumanWarDataList._humanDataList[human._id]
        if nRoomID and nRoomID > 0 and nHumanWarData and nHumanWarData.status ~= DHFIGHT_STATUS_LEAVED then
            local nV3Src = nHumanWarData.v3
            local nV3Temp = nHumanWarData.v3 + v3
            if not enterFloor then
                nHumanWarData.v3 = nV3Temp < 0 and 0 or nV3Temp
            end
            if v3 > 0 or (v3 < 0 and nV3Src > 0) then
                onV3Rank(human, v3, nRoomID)
            end
        end
    end
end

function onCollectDieCB(human, collect, collect_id)
    local nCollectData = DHFightBaseConfig.floorCollectData
    local nFloor = onGetHumanCurFloor(human._id)
    if nFloor and nCollectData[nFloor] then
        for k, v in ipairs(nCollectData[nFloor]) do
            if v == collect_id then
                onAddV3(DHFightIncomeConfig.boxItemAddV3, human)
                break
            end
        end
    end
end

function onV3Rank(human, score, roomID)
    local nHumanUuid = human._id
    local nSceneID = human.scene_id
    local nFloor = onGetHumanCurFloor(human._id)
    local nScoreRankData = RoomRankList[roomID]
    if not nSceneID or nSceneID <= 0 or not RoomRankList or not nScoreRankData then
        return
    end

    local nScore = HumanWarDataList._humanDataList[nHumanUuid].v3

    local nBeforeRank = 0
    local nCurRank = 0

    if #nScoreRankData == 0 then
        onAddRankList(nScoreRankData, 1, human, nScore, nFloor)
    else
        for k, v in ipairs(nScoreRankData) do
            if v[3] == nHumanUuid then
                nBeforeRank = k
                break
            end
        end

        if nBeforeRank == 1 and (nScore >= nScoreRankData[1][2] or #nScoreRankData == 1) then
            nScoreRankData[1][2] = nScore
            nCurRank = 1
        elseif nBeforeRank > 0 and (nScoreRankData[nBeforeRank -1] and nScore <= nScoreRankData[nBeforeRank - 1][2]) and ((nScoreRankData[nBeforeRank + 1] 
            and nScore >= nScoreRankData[nBeforeRank + 1][2]) or nBeforeRank == #nScoreRankData) then
            nScoreRankData[nBeforeRank][2] = nScore
            nCurRank = nBeforeRank
        else
            if nBeforeRank > 0 then
                table.remove(nScoreRankData, nBeforeRank)
            end
            for k = #nScoreRankData, 1, -1 do
                if nScoreRankData[k] then
                    if k == 1 then
                        if nScore < nScoreRankData[k][2] then
                            onAddRankList(nScoreRankData, k + 1, human, nScore, nFloor)
                            nCurRank = k + 1
                            break
                        else
                            onAddRankList(nScoreRankData, 1, human, nScore, nFloor)
                            nCurRank = 1
                            break
                        end
                    else
                        if nScore <= nScoreRankData[k][2] then
                            onAddRankList(nScoreRankData, k + 1, human, nScore, nFloor)
                            nCurRank = k + 1
                            break
                        end
                    end
                end
            end

        end
    end
end

function onAddRankList(rankdata, rank, human, score, floor)
    table.insert(rankdata, rank, {human.name, score, human._id, human.db.zhandouli, floor})
end

function onGetFloorHumanNameColor(floor)
end

function onSendBroadcast(content, type, copyID, roomID)
    local nMsg = Msg.gc.GC_BROADCAST
    nMsg.type = type
    nMsg.msg = content
    CopyL.sendCopy(nMsg, copyID, roomID)
end

function onSendFloodMsg(floor, content, roomID)
    local nFds = onGetFloorFds(floor)
    if nFds[0] > 0 then
        Broadcast.sendBroadcastFDs(nFds, Lang.UP, content)
    end
end

function onGetFloorFds(floor)
    local nFds = {}
    local nLen = 0
    for k in pairs(FloorDataList[floor]) do
        local nHuman = ObjHuman.onlineUuid[k]
        if nHuman and nHuman.fd then
            nLen = nLen + 1
            nFds[nLen] = nHuman.fd
        end
    end
    nFds[0] = nLen
    return nFds
end

function onKingMsg(human)
    local nFloor = onGetHumanCurFloor(human._id)
    if nFloor ~= DHFIGHT_FLOOR_5 then
        return
    end

    local msgErr = Msg.gc.GC_BROADCAST
    msgErr.type = Lang.MOUSE
    if HumanWarDataList._humanDataList[human._id].kingMsgCD then
        if os.time() - HumanWarDataList._humanDataList[human._id].kingMsgCD < DHFightBaseConfig.kingMsgCD then
            msgErr.msg = "宣言冷却中..."
            Msg.send(msgErr, human.fd)
            return
        end
    end

    HumanWarDataList._humanDataList[human._id].kingMsgCD = os.time()
    local nKingMsg = DHFightBaseConfig.kingMsg[math.random(1, #DHFightBaseConfig.kingMsg)]
    nKingMsg = "斗场霸主" .. HtmlUtil.font(human.name, "#00FF00") .. "微微皱眉，道：" .. nKingMsg
    Broadcast.sendBroadcast2World(Lang.UP + Lang.GROSSIP, nKingMsg or "")
    onSendKingMsgData(human)
end

function onSendKingMsgData(human)
    local nSendMsg = Msg.gc.GC_DHFIGHT_KINGMSG
    nSendMsg.cdtime = DHFightBaseConfig.kingMsgCD - (os.time() - HumanWarDataList._humanDataList[human._id].kingMsgCD)
    Msg.send(nSendMsg, human.fd)
end

DailyActFL.onRegisterCallBack(ActDefine.ACT_TYPE_DHFIGHT_ACT, nil, nil, onDHFightRoomEnd)
